import fs from 'fs'
import path from 'path'
import regenerate from 'regenerate'
import N from '@unicode/unicode-13.0.0/General_Category/Number/code-points.js'
import L from '@unicode/unicode-13.0.0/General_Category/Letter/code-points.js'
import Ll from '@unicode/unicode-13.0.0/General_Category/Lowercase_Letter/code-points.js'
import M from '@unicode/unicode-13.0.0/General_Category/Mark/code-points.js'
import Pc from '@unicode/unicode-13.0.0/General_Category/Connector_Punctuation/code-points.js'
import Pd from '@unicode/unicode-13.0.0/General_Category/Dash_Punctuation/code-points.js'
import Pe from '@unicode/unicode-13.0.0/General_Category/Close_Punctuation/code-points.js'
import Pf from '@unicode/unicode-13.0.0/General_Category/Final_Punctuation/code-points.js'
import Pi from '@unicode/unicode-13.0.0/General_Category/Initial_Punctuation/code-points.js'
import Po from '@unicode/unicode-13.0.0/General_Category/Other_Punctuation/code-points.js'
import Ps from '@unicode/unicode-13.0.0/General_Category/Open_Punctuation/code-points.js'
import BPWhiteSpace from '@unicode/unicode-13.0.0/Binary_Property/White_Space/code-points.js'
import combiningDiacriticalMarks from '@unicode/unicode-13.0.0/Block/Combining_Diacritical_Marks/code-points.js'

var combiningDiacriticalMark = regenerate().add(combiningDiacriticalMarks)

var combiningNonspacingMark = regenerate().add(M)

var letter = regenerate().add(L)

var letterLower = regenerate().add(Ll)

var numerical = regenerate().add(N)

var punctuation = regenerate()
  .add(Pc)
  .add(Pd)
  .add(Pe)
  .add(Pf)
  .add(Pi)
  .add(Po)
  .add(Ps)

  // Remove few weirdly-classified symbols:
  // <https://www.unicode.org/faq/punctuation_symbols.html#4>
  .remove('#')
  .remove('&')
  .remove('@')
  .remove('%')
  .remove('‰')
  .remove('‱')
  .remove('*')
  .remove('†')
  .remove('‡')
  .remove('※')

var punctuationClosing = regenerate().add(Pe)

var punctuationFinal = regenerate().add(Pf).add('"').add("'")

var whiteSpace = regenerate().add(BPWhiteSpace)

var word = regenerate()
  .add(combiningDiacriticalMark)
  .add(combiningNonspacingMark)
  .add(letter)
  .add(numerical)

var terminalMarker = regenerate()
  .add('.')
  .add(0x203d)
  .add('?')
  .add('!')
  .add(0x2026)

// Symbols part of surrounding words.
var wordSymbolInner = regenerate()
  .add('-')
  .add('@')
  .add('?')
  .add('=')
  .add('.')
  .add(':')
  .add("'")
  .add('&')
  .add(0x2019) // Right single quote
  .add(0x00ad) // Soft hyphen
  .add(0x00b7) // Hyphen
  .add(0x2010) // Non-breaking hyphen
  .add(0x2011) // Hyphenation point
  .add(0x2027) // Middle dot

// Symbols which can occur multiple times and still be part of surrounding
// words.
var wordSymbolInnerMulti = regenerate().add('_')

// Match closing or final punctuation, or terminal markers that should still be
// included in the previous sentence, even though they follow the sentence’s
// terminal marker.
var reAffixSymbol = new RegExp(
  '^(' +
    punctuationClosing +
    '|' +
    punctuationFinal +
    '|' +
    terminalMarker +
    ')\\1*$'
)

// Match one or more new line characters.
var reNewLine = /^[ \t]*((\r?\n|\r)[\t ]*)+$/

// Match two or more new line characters.
var reNewLineMulti = /^[ \t]*((\r?\n|\r)[\t ]*){2,}$/

// Match sentence-ending markers.
var reTerminalMarker = new RegExp('^((?:' + terminalMarker + ')+)$')

// Match punctuation marks part of surrounding words.
var reWordSymbolInner = new RegExp(
  '^(' +
    '(?:' +
    wordSymbolInner +
    ')' +
    '|' +
    '(?:' +
    wordSymbolInnerMulti +
    ')+' +
    ')$'
)

// Match punctuation marks.
var rePunctuation = new RegExp(punctuation)

// Match numbers.
var reNumerical = new RegExp('^(?:' + numerical + ')+$')

// Match initial digit.
var reDigitStart = /^\d/

// Match initial lowercase letter.
var reLowerInitial = new RegExp('^(?:' + letterLower + ')')

// Match anything, when possible words, white spaces, or astrals.
var reSurrogates = /[\uD800-\uDFFF]/

// Match a word.
var reWord = new RegExp(word)

// Match white space.
var reWhiteSpace = new RegExp(whiteSpace)

fs.writeFileSync(
  path.join('lib', 'expressions.js'),
  [
    '// This module is generated by `script/build-expressions.js`.',
    'export var affixSymbol = ' + reAffixSymbol,
    'export var newLine = ' + reNewLine,
    'export var newLineMulti = ' + reNewLineMulti,
    'export var terminalMarker = ' + reTerminalMarker,
    'export var wordSymbolInner = ' + reWordSymbolInner,
    'export var numerical = ' + reNumerical,
    'export var digitStart = ' + reDigitStart,
    'export var lowerInitial = ' + reLowerInitial,
    'export var surrogates = ' + reSurrogates,
    'export var punctuation = ' + rePunctuation,
    'export var word = ' + reWord,
    'export var whiteSpace = ' + reWhiteSpace,
    ''
  ].join('\n')
)
